﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AMStudio.Common;
using System.Text.RegularExpressions;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using AMStudio.DelegateDispather;
using System.IO.Ports;
using System.IO;

namespace AMStudio.Driver
{
    public class PrinterDriver : IAutomationDriver
    {
        protected ExceptionManager ExManager = EnterpriseLibraryContainer.Current.GetInstance<ExceptionManager>();

        private DelegateDispather.IEventClient eventClient;
        public DelegateDispather.IEventClient EventClient
        {
            get { return eventClient; }
            set { eventClient = value; }
        }
        private SerialPort hardwaredriver;
        private bool alreadyinitialized = false;
        private IExecuteReader result = new ExecuteReader(false);
        private String hardwareName = "ST1_SCANNER";
        public String HardwareName
        {
            get { return hardwareName; }
            set { hardwareName = value; }
        }
        private String hardwareEvent = "ST1_SCANNER_RET";
        private string templet = string.Empty;

        public String HardwareEvent
        {
            get { return hardwareEvent; }
            set { hardwareEvent = value; }
        }
        public virtual int ExecuteNonQuery(string command, params object[] parameters)
        {
            return -1;
        }
        public virtual IExecuteReader ExecuteReader(string command, params object[] parameters)
        {
            result.Success = false;
            try
            {
                switch (command)
                {
                    case "INIT":
                        {
                            if (alreadyinitialized)
                            {
                                result.Success = true;
                            }
                            IEventManager em = parameters[0] as IEventManager;
                            eventClient = new EventClient(em);
                            config = parameters[1] as PrinterConfig;
                            this.hardwareEvent = config.HardwareEvent;
                            this.hardwareName = config.HardwareName;
                            Logger.Write("Start to init hardware " + hardwareName);
                            templet = File.ReadAllText(config.TempletFileName, System.Text.ASCIIEncoding.ASCII);
                            hardwaredriver = new SerialPort();
                            hardwaredriver.PortName = config.SerialPort.PortName;
                            hardwaredriver.BaudRate = config.SerialPort.BandRate;
                            hardwaredriver.Parity = config.SerialPort.Parity;
                            hardwaredriver.DataBits = config.SerialPort.DataBits;
                            hardwaredriver.StopBits = config.SerialPort.StopBits;
                            hardwaredriver.Handshake = config.SerialPort.HandShake;
                            hardwaredriver.WriteTimeout = config.SerialPort.WriteTimeout;
                            hardwaredriver.ReadTimeout = config.SerialPort.ReadTimeout;
                            //hardwaredriver.DataReceived += new SerialDataReceivedEventHandler(hardwaredriver_DataReceived);
                            hardwaredriver.Open();
                            hardwaredriver.Write("~HI");
                            string printerRetrun = string.Empty;
                            for (int i = 0; i < hardwaredriver.ReadTimeout / 100; i++)
                            {
                                System.Threading.Thread.Sleep(100);
                                printerRetrun += hardwaredriver.ReadExisting();
                                if (printerRetrun.IndexOf(config.SerialPort.ETX) >= 0)
                                {
                                    break;
                                }
                            }
                            if (printerRetrun.Contains(config.PrinterModule))
                            {
                                RaiseEvent("CONNECT", true, null);
                                result.Success = true;
                                result.Result = true;
                                alreadyinitialized = true;
                            }
                            else
                            {
                                RaiseEvent("DISCONNECT", true, null);
                                result.Success = true;
                                result.Result = true;
                                alreadyinitialized = true;
                            }
                        }
                        break;
                    case "PRINT":
                        {
                            if (!alreadyinitialized)
                            {
                                break;
                            }

                            string serialNo = parameters[0].ToString();
                            string station = parameters[1].ToString();
                            string content = templet.Replace(config.BarcodeTemplet, serialNo);
                            content = content.Replace(config.TextTemplet, station);
                            hardwaredriver.Write(content);
                            result.Success = true;
                            //result.Result = true;
                        }
                        break;
                    case "CONNECT_STATUS":
                        if (alreadyinitialized)
                        {
                            result.Success = true;
                            result.Result = true;
                        }
                        else
                        {
                            result.Success = false;
                            result.Result = false;
                        }
                        break;
                    case "EXIT":
                        if (hardwaredriver != null)
                        {
                            hardwaredriver.Close();
                        }
                        alreadyinitialized = false;
                        RaiseEvent("DISCONNECT", true, null);
                        break;
                }
            }
            catch (Exception ex)
            {
                ExManager.HandleException(ex, "Policy");
                alreadyinitialized = false;
                RaiseEvent("DISCONNECT", true, null);
                if (hardwaredriver != null)
                    hardwaredriver.Close();
            }
            return result;
        }


        private bool haveReceiveData = false;
        private string receivedData = string.Empty;
        private string myData = string.Empty;
        private PrinterConfig config = null;
        void hardwaredriver_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            receivedData += hardwaredriver.ReadExisting();
            if (receivedData.IndexOf(config.SerialPort.ETX) >= 0)
            {
                haveReceiveData = true;
                receivedData = receivedData.Replace(config.SerialPort.ETX, string.Empty);
                RaiseEvent("DATA_RECEIVE", true, receivedData);
                myData = receivedData;
                receivedData = string.Empty;
            }
        }

        public void RaiseEvent(string command, bool status, object value)
        {
            StationEventArgs arg = new StationEventArgs(hardwareName, command, status, value);
            eventClient.RaiseEvent(hardwareEvent, arg);
        }
    }
}
